
package com.example.videotrim.utils;

import com.example.videotrim.R;

import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.media.MediaPlayer;
import android.provider.MediaStore;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.WindowManager;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class S3dVideo {
    public static final String TAG = "S3dVideo";

    private Context mContext = null;

    private long mMediaId = 0;

    private Object mS3dSurfaceHolder = null;

    private MediaPlayer mMediaPlayer = null;

    private int mIs3d = 1;

    private Object m3dInfo = null;

    private Object m2dInfo = null;

    private Bitmap m3dIcon = null;

    private int WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_NONE = 0;

    private int WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_SS = 0;

    private int WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_TB = 0;

    private int WINDOWMANAGER__LAYOUTPARAMS__S3D_ORDER_LR = 0;

    private int WINDOWMANAGER__LAYOUTPARAMS__S3D_ORDER_RL = 0;

    private int MEDIASTORE__MEDIA_VIDEO_3D_TB = 0;

    private int MEDIASTORE__MEDIA_VIDEO_3D_SEI_TB = 0;

    private int MEDIASTORE__MEDIA_VIDEO_3D_LR = 0;

    private int MEDIASTORE__MEDIA_VIDEO_3D_SEI_LR = 0;

    private int MEDIASTORE__MEDIA_VIDEO_3D_RL = 0;

    private int MEDIASTORE__MEDIA_VIDEO_3D_SEI_RL = 0;

    private int MEDIASTORE__MEDIA_VIDEO_NORMAL = 1;

    private String MEDIASTORE__VIDEO__MEDIA__IS_3D = null;

    private Class mS3dInfoClass = null;

    private Constructor mS3dInfoConstructor = null;

    private Class mS3dSurfaceHolderClass = null;

    private Method mS3dSurfaceHolderSetS3dInfoMethod = null;

    private Method mS3dSurfaceHolderGetS3dInfoMethod = null;

    private Class mMediaPlayerClass = null;

    private Method mMediaPlayerNotifyS3dChangedMethod = null;

    public S3dVideo(Context context, long mediaId) {
        mContext = context;
        mMediaId = mediaId;
    }

    public void init() {
        mS3dSurfaceHolder = null;
        mMediaPlayer = null;

        try {
            WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_NONE = WindowManager.LayoutParams.class.getField(
                    "S3D_TYPE_NONE").getInt(null);
            WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_SS = WindowManager.LayoutParams.class.getField(
                    "S3D_TYPE_SS").getInt(null);
            WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_TB = WindowManager.LayoutParams.class.getField(
                    "S3D_TYPE_TB").getInt(null);
            WINDOWMANAGER__LAYOUTPARAMS__S3D_ORDER_LR = WindowManager.LayoutParams.class.getField(
                    "S3D_ORDER_LR").getInt(null);
            WINDOWMANAGER__LAYOUTPARAMS__S3D_ORDER_RL = WindowManager.LayoutParams.class.getField(
                    "S3D_ORDER_RL").getInt(null);

            MEDIASTORE__MEDIA_VIDEO_3D_TB = MediaStore.class.getField("MEDIA_VIDEO_3D_TB").getInt(
                    null);
            MEDIASTORE__MEDIA_VIDEO_3D_SEI_TB = MediaStore.class.getField("MEDIA_VIDEO_3D_SEI_TB")
                    .getInt(null);
            MEDIASTORE__MEDIA_VIDEO_3D_LR = MediaStore.class.getField("MEDIA_VIDEO_3D_LR").getInt(
                    null);
            MEDIASTORE__MEDIA_VIDEO_3D_SEI_LR = MediaStore.class.getField("MEDIA_VIDEO_3D_SEI_LR")
                    .getInt(null);
            MEDIASTORE__MEDIA_VIDEO_3D_RL = MediaStore.class.getField("MEDIA_VIDEO_3D_RL").getInt(
                    null);
            MEDIASTORE__MEDIA_VIDEO_3D_SEI_RL = MediaStore.class.getField("MEDIA_VIDEO_3D_SEI_RL")
                    .getInt(null);
            MEDIASTORE__MEDIA_VIDEO_NORMAL = MediaStore.class.getField("MEDIA_VIDEO_NORMAL")
                    .getInt(null);

            MEDIASTORE__VIDEO__MEDIA__IS_3D = (String) MediaStore.Video.Media.class.getField(
                    "IS_3D").get(null);

            mS3dInfoClass = Class.forName("android.view.S3DInfo");
            mS3dInfoConstructor = mS3dInfoClass.getConstructor(new Class[] {
                    boolean.class, int.class, int.class
            });

            mS3dSurfaceHolderClass = Class.forName("android.view.S3DSurfaceHolder");
            mS3dSurfaceHolderSetS3dInfoMethod = mS3dSurfaceHolderClass.getMethod("setS3DInfo",
                    new Class[] {
                        mS3dInfoClass
                    });
            mS3dSurfaceHolderGetS3dInfoMethod = mS3dSurfaceHolderClass.getMethod("getS3DInfo",
                    new Class[] {});

            mMediaPlayerClass = Class.forName("android.media.MediaPlayer");
            mMediaPlayerNotifyS3dChangedMethod = mMediaPlayerClass.getMethod("notifyS3DChanged",
                    new Class[] {});
        } catch (Throwable e) {
            e.printStackTrace();
        }

        mIs3d = getS3dType(mContext.getContentResolver(), mMediaId);
        Log.v(TAG, "S3dVideo --> mIs3d:" + mIs3d);

        try {
            m2dInfo = mS3dInfoConstructor.newInstance(true,
                    WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_NONE,
                    WINDOWMANAGER__LAYOUTPARAMS__S3D_ORDER_LR);
        } catch (Throwable e) {
            e.printStackTrace();
        }

        m3dInfo = make3dInfo();

        BitmapFactory.Options options = new BitmapFactory.Options();
        // options.inSampleSize = 2;
        m3dIcon = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.thumb_3d,
                options);
    }

    public boolean setS3dDisplay(boolean isS3dMode) {
        // FIXME:
        if (mContext.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
            return false;

        if (mS3dSurfaceHolder != null && mMediaPlayer != null) {
            Log.v(TAG, "setS3dDisplay --> isS3dMode:" + isS3dMode);
            if (isS3dMode) {
                try {
                    mS3dSurfaceHolderSetS3dInfoMethod.invoke(mS3dSurfaceHolder, m3dInfo);
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            } else {
                try {
                    mS3dSurfaceHolderSetS3dInfoMethod.invoke(mS3dSurfaceHolder, m2dInfo);
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
            try {
                mMediaPlayerNotifyS3dChangedMethod.invoke(mMediaPlayer);
            } catch (Throwable e) {
                e.printStackTrace();
            }
            return true;
        }
        return false;
    }

    public void setSurfaceHolder(SurfaceHolder sh) {
        if (mS3dSurfaceHolderClass != null) {
            if (mS3dSurfaceHolderClass.isInstance(sh)) {
                mS3dSurfaceHolder = sh;
            }
        }
    }

    public void setMediaPlayer(MediaPlayer mp) {
        mMediaPlayer = mp;
    }

    public boolean isS3dVideo() {
        boolean result = false;
        if (mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_TB || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_SEI_TB
                || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_LR
                || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_SEI_LR
                || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_RL
                || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_SEI_RL)
            result = true;
        else if (mIs3d == MEDIASTORE__MEDIA_VIDEO_NORMAL)
            result = false;
        return result;
    }

    public boolean isS3dMode() {
        if (mS3dSurfaceHolder == null)
            return false;

        // FIXME:
        if (mContext.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
            return false;

        boolean isS3dMode = false;

        try {
            Object s3dInfo = mS3dSurfaceHolderGetS3dInfoMethod.invoke(mS3dSurfaceHolder);
            int type = mS3dInfoClass.getField("type").getInt(s3dInfo);
            isS3dMode = (type == WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_NONE) ? false : true;
        } catch (Throwable e) {
            e.printStackTrace();
        }

        return isS3dMode;
    }

    public Bitmap getThumbnail(Bitmap bitmap) {
        if (bitmap == null)
            return null;

        Bitmap halfBitmap = null;
        Bitmap scaledBitmap = null;
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        if (mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_TB || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_SEI_TB)
            halfBitmap = Bitmap.createBitmap(bitmap, 0, 0, width - 1, height / 2 - 1);
        else if (mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_LR
                || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_SEI_LR
                || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_RL
                || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_SEI_RL)
            halfBitmap = Bitmap.createBitmap(bitmap, 0, 0, width / 2 - 1, height - 1);

        if (halfBitmap != null)
            scaledBitmap = Bitmap.createScaledBitmap(halfBitmap, width, height, true);

        if (scaledBitmap != null) {
            Canvas canvas = new Canvas(scaledBitmap);
            Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
            int iconX = width - m3dIcon.getWidth();
            int iconY = height - m3dIcon.getHeight();
            iconX = iconX > 0 ? iconX : 0;
            iconY = iconY > 0 ? iconY : 0;
            canvas.drawBitmap(m3dIcon, iconX, iconY, paint);

            return scaledBitmap;
        }

        return bitmap;
    }

    private int getS3dType(ContentResolver cr, long mediaId) {
        int type = MEDIASTORE__MEDIA_VIDEO_NORMAL;

        String[] mediaColumns = {
            MEDIASTORE__VIDEO__MEDIA__IS_3D
        };
        Cursor cursor = cr.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, mediaColumns, "_ID="
                + mediaId, null, null);
        if (cursor.getCount() == 0)
            return MEDIASTORE__MEDIA_VIDEO_NORMAL;
        cursor.moveToFirst();
        type = cursor.getInt(cursor.getColumnIndex(MEDIASTORE__VIDEO__MEDIA__IS_3D));
        if (type == -1)
            type = MEDIASTORE__MEDIA_VIDEO_NORMAL;
        return type;
    }

    private Object make3dInfo() {
        boolean disableAutoDetection = false;
        int type = WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_NONE;
        int order = WINDOWMANAGER__LAYOUTPARAMS__S3D_ORDER_LR;

        if (mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_TB || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_SEI_TB) {
            disableAutoDetection = true;
            type = WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_TB;
        } else if (mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_LR
                || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_SEI_LR) {
            disableAutoDetection = true;
            type = WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_SS;
            order = WINDOWMANAGER__LAYOUTPARAMS__S3D_ORDER_LR;
        } else if (mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_RL
                || mIs3d == MEDIASTORE__MEDIA_VIDEO_3D_SEI_RL) {
            disableAutoDetection = true;
            type = WINDOWMANAGER__LAYOUTPARAMS__S3D_TYPE_SS;
            order = WINDOWMANAGER__LAYOUTPARAMS__S3D_ORDER_RL;
        }

        Object newS3dInfoObject = null;
        try {
            newS3dInfoObject = mS3dInfoConstructor.newInstance(disableAutoDetection, type, order);
        } catch (Throwable e) {
            e.printStackTrace();
        }

        return newS3dInfoObject;
    }
}
